package com.sumer.psychology.friend.domain.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import com.sumer.psychology.common.Assert;
import com.sumer.psychology.common.domain.model.ConcurrencySafeEntity;

/**
 * 一个社交成员
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/8/27
 * Time: 16:16
 */
public class Member extends ConcurrencySafeEntity {
    private MemberId memberId;
    private Date createTime;
    private Date lastModifyTime;

    private Set<MemberId> friends;

    public Member() {
    }

    public Member(MemberId memberId) {
        setCreateTime(new Date());
        setMemberId(memberId);
        setFriends(new HashSet<MemberId>(0));
    }

    /**
     * 申请好友
     *
     * @param aFriend      friend
     * @param requestWords words
     */
    public void requestFriend(Member aFriend, String requestWords) {
        apply(new FriendRequestedEvent(
                memberId(),
                aFriend.memberId(),
                requestWords));
    }

    /**
     * 拒绝好友
     *
     * @param aFriend     friend
     * @param rejectWords words
     * @param messageId   message
     */
    public void rejectFriend(Member aFriend, String rejectWords, String messageId) {
        apply(new FriendRejectedEvent(
                memberId(),
                aFriend.memberId(),
                rejectWords,
                messageId));
    }

    /**
     * 添加好友
     *
     * @param aFriend friend
     */
    public void addFriend(Member aFriend) {
        Assert.notNull(aFriend, "朋友不能为空");

        if (!haveFriend(aFriend)) {
            setLastModifyTime(new Date());
            friends().add(aFriend.memberId);
        }

    }

    /**
     * 删除好友
     *
     * @param deleteFriend friend
     */
    public void deleteFriend(Member deleteFriend) {
        Assert.notNull(deleteFriend, "朋友不能为空");

        if (haveFriend(deleteFriend)) {
            setLastModifyTime(new Date());
            friends().remove(deleteFriend.memberId());
        }

    }

    /**
     * 是我的好友吗
     *
     * @param friend a friend
     * @return is my friend
     */
    public boolean haveFriend(Member friend) {
        return friends().contains(friend.memberId());
    }

    public MemberId memberId() {
        return memberId;
    }

    /**
     * 朋友列表
     *
     * @return friends
     */
    public Set<MemberId> friends() {
        if (friends == null) {
            setFriends(new HashSet<MemberId>(0));
        }
        return friends;
    }

    public Date createTime() {
        return createTime;
    }

    public Date lastModifyTime() {
        return lastModifyTime;
    }

    private void setMemberId(MemberId memberId) {
        Assert.notNull(memberId, "id不能为空");
        Assert.notEmpty(memberId.identity(), "id不能为空");

        this.memberId = memberId;
    }

    private void setCreateTime(Date createTime) {
        Assert.notNull(createTime, "创建日期不能为空");
        this.createTime = createTime;
    }

    private void setLastModifyTime(Date lastModifyTime) {
        this.lastModifyTime = lastModifyTime;
    }

    private void setFriends(Set<MemberId> friends) {
        Assert.notNull(friends);

        this.friends = friends;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Member member = (Member) o;

        if (memberId != null ? !memberId.equals(member.memberId) : member.memberId != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return memberId != null ? memberId.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "Member{" +
                "memberId=" + memberId +
                ", createTime=" + createTime +
                ", lastModifyTime=" + lastModifyTime +
                '}';
    }
}
